#include "stdafx.h"
#include "triangulo.h"
#include <iostream.h>
#include "SDL.h"
#include "punto.h"
#include "figura.h"
#include "math.h"

//--------------------------------------------------------------------------------------------/

triangulo::triangulo(SDL_Surface* screen) :figura(screen) {}
//--------------------------------------------------------------------------------------------/

triangulo::triangulo(punto puntoA, punto puntoB, punto puntoC, SDL_Surface* screen):figura(screen), puntoA(puntoA), puntoB(puntoB), puntoC(puntoC) {}
//--------------------------------------------------------------------------------------------/

void triangulo::setPuntoA(punto punto) {
	this->puntoA = punto;
}

//--------------------------------------------------------------------------------------------/

void triangulo::setPuntoB(punto punto) {
	this->puntoB = punto;
}
//--------------------------------------------------------------------------------------------/

void triangulo::setPuntoC(punto punto) {
	this->puntoC = punto;
}
//--------------------------------------------------------------------------------------------/

punto& triangulo::getPuntoA() {
	return puntoA;
}
//--------------------------------------------------------------------------------------------/

punto& triangulo::getPuntoB() {
	return puntoB;
}
//--------------------------------------------------------------------------------------------/

punto& triangulo::getPuntoC() {
	return puntoC;
}

//--------------------------------------------------------------------------------------------/

bool evaluoInterno(float Yinicial, punto puntoA,punto puntoB, punto* minimoXY)
{
	float pendiente, ordenadaAlorigen;
	float nuevoX, nuevoY;

	//saco la pendiente y la ordenada al origen -> y= m x + b
	ordenadaAlorigen =( ( -puntoA.getX()/(puntoB.getX()-puntoA.getX()))*(puntoB.getY()-puntoA.getY()))+ puntoA.getY();
	if ((puntoB.getX() - puntoA.getX()) != 0)
	{
		pendiente =(puntoB.getY()-puntoA.getY()) /(puntoB.getX()- puntoA.getX());
		//no es ininito la pendiente
		nuevoX = ( Yinicial-ordenadaAlorigen ) / (pendiente);
		nuevoY = Yinicial;
		minimoXY->setX(nuevoX);
		minimoXY->setY(nuevoY);
	}
	else
	{
		//es infinito la pendiente
		nuevoX = puntoA.getX();
		nuevoY = Yinicial;
		minimoXY->setX(nuevoX);
		minimoXY->setY(nuevoY);
	}
	//veo si ta adentro del triangulo
	if ((puntoA.getX() >= nuevoX && puntoB.getX() <= nuevoX) || (puntoB.getX() >= nuevoX && puntoA.getX() <= nuevoX))
	{
		if (((puntoA.getY() >= nuevoY && puntoB.getY() <= nuevoY) || (puntoB.getY() >= nuevoY && puntoA.getY() <= nuevoY)) )
		return true;
	}

	return false;



}

//--------------------------------------------------------------------------------------------/

void triangulo::graficarRellenoTriangulo() {

	float alturaMinima, alturaMaxima, calculoAncho;
	punto minimoXY1, minimoXY2, minimoXY3;
	punto* puntoInicial;
	punto* puntoFinal;
	bool entreAyB, entreByC, entreAyC;
	SDL_Rect recta;
	Uint32 colorBorde = SDL_MapRGB(screen->format, colorRellenoGrafico.getRojo(),colorRellenoGrafico.getVerde(), colorRellenoGrafico.getAzul());

	//busco el minimo y maximo posicion y del triangulo
	alturaMaxima = alturaMinima = puntoA.getY();

	if (puntoB.getY() < alturaMinima)
		alturaMinima = puntoB.getY();
	else
		alturaMaxima = puntoB.getY();

	if (puntoC.getY() < alturaMinima)
		alturaMinima = puntoC.getY();
	if (puntoC.getY() > alturaMaxima)
		alturaMaxima = puntoC.getY();

	alturaMinima += 0.1;  //corta
	while (alturaMinima < alturaMaxima)  //voy avanzando de a poco hasta maximo
	{
	entreAyB = evaluoInterno(alturaMinima, puntoA, puntoB, &minimoXY1);

	entreByC = evaluoInterno(alturaMinima, puntoB, puntoC, &minimoXY2);
	
	entreAyC = evaluoInterno(alturaMinima, puntoC, puntoA, &minimoXY3);

	if (entreAyB && entreByC)
	{
		if (minimoXY1.getX() < minimoXY2.getX())
		{
				puntoInicial = &minimoXY1;
				puntoFinal = &minimoXY2;
		}

		else
		{
				puntoInicial = &minimoXY2;
				puntoFinal = &minimoXY1;
		}
	}

	else if (entreAyB && entreAyC)
	{
		if (minimoXY1.getX() < minimoXY3.getX())
		{
			puntoInicial = &minimoXY1;
			puntoFinal = &minimoXY3;
		}
		else
		{
			puntoInicial = &minimoXY3;
			puntoFinal = &minimoXY1;
		}
	}
	else if (entreByC && entreAyC)
	{
		if (minimoXY2.getX() < minimoXY3.getX())
		{
			puntoInicial = &minimoXY2;
			puntoFinal = &minimoXY3;
		}
		else
		{
			puntoInicial = &minimoXY3;
			puntoFinal = &minimoXY2;
		}
	}
			recta.x = (int) puntoInicial->getX() +1;
			recta.y = (int) puntoInicial->getY() ;
			calculoAncho =puntoFinal->getX()+1 - puntoInicial->getX() ;
			recta.h = 1;



			recta.w = (int)calculoAncho;

			SDL_FillRect(screen, &recta, colorBorde);
			SDL_UpdateRect(screen, recta.x, recta.y, recta.w, recta.h);

			//transparencia o 1
			alturaMinima =alturaMinima+ 0.1;
	}
}

//--------------------------------------------------------------------------------------------/

void graficarLineaTriangulo(SDL_Surface* screen, punto puntoInicial, punto puntoFinal,color color)
{
	punto unPunto;
	int errorEnX,errorEnY, tamanio, cantidad,
	VerX, VerY, xInicial, yInicial, xFinal, yFinal,diferencialX, diferencialY;

	xInicial = (int)puntoInicial.getX();
	xFinal = (int)puntoFinal.getX();
	yInicial = (int)puntoInicial.getY();
	yFinal =(int) puntoFinal.getY();

	diferencialX = xFinal - xInicial;
	diferencialY = yFinal - yInicial;

	if (diferencialX > 0)
		VerX = 1;
	else if (diferencialX == 0)
		VerX = 0;
	else
		VerX = -1;

	if (diferencialY > 0)
		VerY = 1;
	else if (diferencialY == 0)
		VerY = 0;
	else
		VerY = -1;

	diferencialX = abs(diferencialX);
	diferencialY = abs(diferencialY);

	if (diferencialX > diferencialY)
		tamanio = diferencialX;
	else
		tamanio = diferencialY;

	errorEnX = 0;
	errorEnY = 0;


	for (cantidad = 0; cantidad <= tamanio+1; cantidad++)
	{
	unPunto.ponerUnPixel(screen, xInicial, yInicial, color);
	errorEnX =errorEnX + diferencialX;
	errorEnY =errorEnY + diferencialY;

	if (errorEnX > tamanio) 
	{
		xInicial = xInicial + VerX;
		errorEnX =errorEnX - tamanio;
	}
	if (errorEnY > tamanio) 
	{
		yInicial = yInicial + VerY;
		errorEnY =errorEnY- tamanio;
	}
	}
}

//--------------------------------------------------------------------------------------------/
void triangulo::graficar() {

		graficarRellenoTriangulo();

		graficarLineaTriangulo(screen,puntoA,puntoB,colorBordeGrafico);
		graficarLineaTriangulo(screen,puntoB,puntoC,colorBordeGrafico);
		graficarLineaTriangulo(screen,puntoC,puntoA,colorBordeGrafico);
}
//--------------------------------------------------------------------------------------------/
triangulo::~triangulo() {}

//--------------------------------------------------------------------------------------------/





